package com.dragon.test.springbootdemo.controller;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.util.Date;

import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * @Author: longtao
 * @Date: 2019/6/4
 * @Version: 1.0
 * @Description:
 */
@Controller
public class JWTController {

    public final static String ISSUER = "Issuer";

    public final static String SUBJECT = "Client";

    public final static String CLAIM_APPID = "appId";

    public final static String CLAIM_PARTNERID = "partnerId";

    public final static String CLAIM_DEVICEID = "deviceId";

    public final static long TOKENEXPIRETIME = 360000L;


    @RequestMapping(value = "/jwt/encode", method = POST)
    @ResponseBody
    public String testJWTEncode(String secretKey, long appId, long partnerId, String deviceId) {

        String token = createToken(secretKey, appId, partnerId, deviceId);

        return token;
    }


    @RequestMapping(value = "/jwt/decode", method = POST)
    @ResponseBody
    public String testJWTDecode(String token, String secretKey) {

        String sourceJwt = verifyToke(token, secretKey);

        return sourceJwt;
    }


    /**
     * @param secretKey
     * @param appId
     * @param partnerId
     * @param deviceId
     * @return
     */
    public static String createToken(String secretKey, long appId, long partnerId, String deviceId) {
        Algorithm al;
        try {
            al = Algorithm.HMAC256(secretKey);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
        Date expire = new Date(System.currentTimeMillis() + TOKENEXPIRETIME);
        String token = JWT.create()
                .withIssuer(ISSUER)
                .withSubject(SUBJECT)
                .withClaim(CLAIM_APPID, appId)
                .withClaim(CLAIM_PARTNERID, partnerId)
                .withClaim(CLAIM_DEVICEID, deviceId)
                .withExpiresAt(expire)
                .sign(al);
        return token;
    }


    /**
     * @param token
     * @param secretKey
     * @return
     */
    public static String verifyToke(String token, String secretKey) {
        JWTVerifier verifier = null;
        try {
            verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        DecodedJWT sourceJwt = null;
        try {
            sourceJwt = verifier.verify(token);
        } catch (TokenExpiredException e) {
            e.printStackTrace();
        } catch (JWTVerificationException e) {
            e.printStackTrace();
        }

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("ExpiresAt:").append(sourceJwt.getExpiresAt());
        stringBuffer.append(";Claims:").append(sourceJwt.getClaims());
        stringBuffer.append(";Algorithm:").append(sourceJwt.getAlgorithm());

        return stringBuffer.toString();
    }


}
